﻿namespace Pub.Class
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Text;

    public class IniFile
    {
        private readonly string path;

        public IniFile(string iniPath)
        {
            this.path = iniPath;
        }

        private IList<string> ByteToString(byte[] sectionByte)
        {
            return (from p in new ASCIIEncoding().GetString(sectionByte).Split(new char[1]).ToList<string>()
                where p.Trim().Length > 0
                select p).Distinct<string>().ToList<string>();
        }

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string defVal, byte[] retVal, int size, string filePath);
        public IList<string> ReadKeys(string section)
        {
            return this.ByteToString(this.ReadKeys(section, null));
        }

        public byte[] ReadKeys(string section, string key)
        {
            byte[] retVal = new byte[0xff];
            GetPrivateProfileString(section, key, "", retVal, 0xff, this.path);
            return retVal;
        }

        public IList<string> ReadSections()
        {
            return this.ByteToString(this.ReadKeys(null, null));
        }

        public string ReadValue(string section, string key)
        {
            StringBuilder retVal = new StringBuilder(0xff);
            GetPrivateProfileString(section, key, "", retVal, 0xff, this.path);
            return retVal.ToString();
        }

        public IDictionary<string, IDictionary<string, string>> ReadValues()
        {
            IDictionary<string, IDictionary<string, string>> dictionary = new Dictionary<string, IDictionary<string, string>>();
            foreach (string str in this.ReadSections())
            {
                dictionary.Add(str, this.ReadValues(str));
            }
            return dictionary;
        }

        public IDictionary<string, string> ReadValues(string section)
        {
            IDictionary<string, string> dictionary = new Dictionary<string, string>();
            foreach (string str in this.ReadKeys(section))
            {
                dictionary.Add(str, this.ReadValue(section, str));
            }
            return dictionary;
        }

        public IniFile Remove(string section)
        {
            if (!section.IsNullEmpty())
            {
                WritePrivateProfileString(section, null, null, this.path);
            }
            return this;
        }

        public IniFile Remove(string section, string key)
        {
            if (!section.IsNullEmpty() && !key.IsNullEmpty())
            {
                WritePrivateProfileString(section, key, null, this.path);
            }
            return this;
        }

        public IniFile RemoveAll()
        {
            foreach (string str in this.ReadSections())
            {
                this.Remove(str);
            }
            return this;
        }

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        public IniFile WriteValue(string section, string key, string value)
        {
            if ((!section.IsNullEmpty() && !key.IsNullEmpty()) && !value.IsNullEmpty())
            {
                WritePrivateProfileString(section, key, value, this.path);
            }
            return this;
        }

        public string this[string section, string key]
        {
            get
            {
                return this.ReadValue(section, key);
            }
            set
            {
                this.WriteValue(section, key, value);
            }
        }
    }
}

